package com.plug.controller.util;

import com.plug.common.spring.utils.ApplicationContextHelper;
import com.plug.controller.util.cache.KeyUtil;
import com.plug.entity.*;
import com.plug.service.IPlugBackupRecordService;
import com.plug.service.IPlugRecordService;
import com.plug.service.IPlugTaskStateService;
import com.plug.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * Created by slayes on 2017/1/17.
 */
public class TaskThread implements Runnable {

    private Logger logger = LoggerFactory.getLogger(getClass());

    private String column;
    private PlugContrast plugContrast;
    private IPlugRecordService plugRecordService;
    private Long[] indexLong;
    private HttpServletRequest request;
    private PlugDatasource srcDataSource;
    private PlugDatasource tgtDataSource;
    private Long total;
    private IPlugTaskStateService plugTaskStateService;

    public TaskThread(PlugDatasource srcDataSource,PlugDatasource tgtDataSource,PlugContrast plugContrast,String column,
                      Long[] indexLong,Long total,IPlugRecordService plugRecordService,IPlugTaskStateService plugTaskStateService,HttpServletRequest request){
        this.plugRecordService = plugRecordService;
        this.column = column;
        this.plugContrast = plugContrast;
        this.indexLong = indexLong;
        this.request = request;
        this.total = total;
        this.srcDataSource = srcDataSource;
        this.plugTaskStateService = plugTaskStateService;
        this.tgtDataSource = tgtDataSource;
    }


    public void run() {

        //根据传入条件查询源备份数据集
        Map<String, Map<String, Object>> srcResultMap = null;

        //根据传入条件查询目标数据集
        Map<String, Map<String, Object>> tgtResultMap = null;

        IPlugBackupRecordService plugBackupRecordService=
                (IPlugBackupRecordService) ApplicationContextHelper.getBean("plugBackupRecordService");
        List<PlugBackupRecord> plugBackupRecordList = new ArrayList<>(); //任务记录list
        PlugBackupRecord plugLoggerRecord=new PlugBackupRecord(); //一个空的任务记录
        //记录即时任务状态
        String taskName=plugContrast.getName();


        //拼接定时任务名称
        String new_task_name = "即时任务_" + taskName + "_" + new Date().getTime();

        //
        PlugTaskState plugTaskState = plugTaskStateService.selectByName(new_task_name);
        if(plugTaskState==null) {
            plugTaskState=new PlugTaskState();//新建一条任务状态记录
            plugTaskState.setTaskName(new_task_name);//set task name
        }

        Long pages = (indexLong[1] - indexLong[0])/KeyUtil.compareMaxNumber;
        Integer page = Integer.valueOf(pages.toString());
        if(page == 0)
            page += 1;

        if(page > 1 && (indexLong[1] - indexLong[0])%KeyUtil.compareMaxNumber > 0)
            page += 1;

        String uuid = UUID.randomUUID().toString().toUpperCase();

        if(indexLong[0] >= indexLong[1]){
            page = 0;
//            indexLong[0]=1L;
        }
        logger.info("-----------pages:{}------{}-------{}----{}-----",indexLong[1],(indexLong[1] - indexLong[0])/KeyUtil.compareMaxNumber,indexLong[0],KeyUtil.compareMaxNumber);
        for (int i = 0; i < page; i++) {

            try {
                Long[] primaryKeys = new Long[2];
                primaryKeys[0] = indexLong[0] + (KeyUtil.compareMaxNumber * i);
                primaryKeys[1] = indexLong[0] + (KeyUtil.compareMaxNumber * (i + 1));

                srcResultMap = plugRecordService.findHistoryRecord(srcDataSource, plugContrast.getSrcTab(),primaryKeys, column, plugContrast);
                tgtResultMap = plugRecordService.findHistoryRecord(tgtDataSource, plugContrast.getTgtTab(), primaryKeys, column, plugContrast);

                plugLoggerRecord.setSrcDatabase(srcDataSource.getDsDesc());//任务记录中源数据库名
                plugLoggerRecord.setTgtDatabase(tgtDataSource.getDsDesc());//任务记录中目标数据库名
                plugLoggerRecord.setSrcTable(plugContrast.getSrcTab());//设置任务记录中的源表
                plugLoggerRecord.setTgtTable(plugContrast.getTgtTab());//设置任务记录中的目标表
                plugLoggerRecord.setPlugContrastId(plugContrast.getId());//设置任务记录中的备份任务配置表ID
                plugLoggerRecord.setActionType(new_task_name);//设置任务记录中的任务名

                List<PlugRecord> plugRecordList = new ArrayList<>();
                for (String key : tgtResultMap.keySet()){
                    Map<String, Object> srcMap = srcResultMap.get(key);
                    Map<String, Object> tgtMap = tgtResultMap.get(key);
                    String srcData = "";//行源数据
                    String tgtData = "";//行目标数据
                    String srcColumn = "";
                    String tgtColumn = "";
                    if(srcResultMap.containsKey(key)) {
                        for(String str : tgtMap.keySet()) {
                            srcColumn += str + ",&,";
                            tgtColumn += str + ",&,";
                            srcData += StringUtils.convertString(srcMap.get(str));
                            srcData += ",&,";
                            tgtData += StringUtils.convertString(tgtMap.get(str));
                            tgtData += ",&,";
                        }
                    } else {
                        for(String str : tgtMap.keySet()) {
                            srcColumn += str + ",&,";
                            tgtColumn += str + ",&,";
                            srcData += "    ,&,    ";
                            tgtData += StringUtils.convertString(tgtMap.get(str));
                            tgtData += ",&,";
                        }
                    }
                    if(!srcData.equals(tgtData)){
                        PlugRecord pl = new PlugRecord();
                        pl.setCreatetime(new Date());
                        pl.setSrcDesc(srcData);
                        pl.setTgtDesc(tgtData);
                        pl.setSrcColumn(srcColumn);
                        pl.setTgtColumn(tgtColumn);
                        pl.setCrId(uuid);
                        plugRecordList.add(pl);
                    }
                }
                for (String key : srcResultMap.keySet()){
                    Map<String, Object> srcMap = srcResultMap.get(key);
                    Map<String, Object> tgtMap = tgtResultMap.get(key);
                    String srcData = "";//行源数据
                    String tgtData = "";//行目标数据
                    String srcColumn = "";
                    String tgtColumn = "";
                    if(!tgtResultMap.containsKey(key)) {
                        for(String str : srcMap.keySet()) {
                            srcColumn += str + ",&,";
                            tgtColumn += str + ",&,";
                            tgtData += "    ,&,    ";
                            srcData += StringUtils.convertString(srcMap.get(str));
                            srcData += ",&,";
                        }
                    }
                    if(!srcData.equals(tgtData)){
                        PlugRecord pl = new PlugRecord();
                        pl.setCreatetime(new Date());
                        pl.setSrcDesc(srcData);
                        pl.setTgtDesc(tgtData);
                        pl.setSrcColumn(srcColumn);
                        pl.setTgtColumn(tgtColumn);
                        pl.setCrId(uuid);
                        plugRecordList.add(pl);
                    }
                }
                PlugOperationRecord plugOperationRecord = plugRecordService.findByID(uuid);//操作人员记录表
                StringBuffer desc = new StringBuffer();
                if(plugOperationRecord == null){
                    plugOperationRecord = new PlugOperationRecord();
                    plugOperationRecord.setId(uuid);
                    plugOperationRecord.setCreatetime(new Date());
                    logger.info("--------------{}--------------", "数据源库名111111");
                    desc.append("数据源库名：" + srcDataSource.getDsName() + ",即时任务：" + tgtDataSource.getDsName() + ";");
                    desc.append("数据源表名："+plugContrast.getSrcTab()+",备份表名："+plugContrast.getTgtTab()+";");
                    desc.append("本次对比共有："+plugRecordList.size()+"条数据不一致；");
                    plugOperationRecord.setOperationip("127.0.0.1");
                    plugOperationRecord.setUserId(1L);
                    plugOperationRecord.setCtId(plugContrast.getId());
                } else {
                    String desc1 = plugOperationRecord.getDescs();
                    logger.info("--------------{}--------------", desc1.indexOf("有：") + 2,desc1.indexOf("条数"));
                    Integer count = Integer.valueOf(desc1.substring(desc1.indexOf("有：") + 2,desc1.indexOf("条数")));
                    desc.append("即时任务：" + srcDataSource.getDsName() + "(" + tgtDataSource.getDsName() + ")");
                    desc.append("->"+plugContrast.getSrcTab()+"("+plugContrast.getTgtTab()+")");
                    desc.append("本次对比共有："+(plugRecordList.size() + count)+"条数据不一致；");
                    plugOperationRecord.setCreatetime(new Date());
                    plugOperationRecord.setOperationip("127.0.0.1");
                }
                plugOperationRecord.setDescs(desc.toString());
                logger.info("------------plugRecordList.size()：{}---------", plugRecordList.size());
                if(plugRecordList.size() > 0) {
                    plugRecordService.saveRecordAndOperation(plugRecordList, plugOperationRecord);
                }

                //起始ID  indexLong[0]  每次对比开始ID indexLong[0] + (i * 2000) 终止行 indexLong[0] + ((i + 1) * 2000) 总条数 total
                logger.info("------开始ID：{}-------即时任务对比执行到-{},{}--------------------------------", indexLong[0],i * KeyUtil.compareMaxNumber,indexLong[0] + (i * KeyUtil.compareMaxNumber));


//                设置任务记录中的起始和终止行
                Long fromIndex= primaryKeys[0];
                if(primaryKeys[0]>indexLong[1]){
                    primaryKeys[0]=indexLong[1];
                }
                Long toIndex= primaryKeys[1];
                if(toIndex > indexLong[1]){
                    toIndex=indexLong[1];
                }

                plugLoggerRecord.setFromNumber(Integer.valueOf(fromIndex.toString()));
                plugLoggerRecord.setToNumber(Integer.valueOf(toIndex.toString()));

                plugTaskState.setEndTime(new Date());

                if(i == page - 1){
                    plugTaskState.setTaskState("运行结束...请手动删除本条任务...");
                    plugTaskState.setMessage("从" + indexLong[0] + "运行至" +indexLong[1]+ ",本次对比结束" );
                } else {
                    plugTaskState.setTaskState("运行中...请刷新查看进度...");
                    plugTaskState.setMessage("从" + indexLong[0] + "运行至" +indexLong[1]+"行,本次从第" + fromIndex + "行至第"+toIndex+"行");
                }


                //查询是否已存在记录
                PlugTaskState find_plug_task_state = plugTaskStateService.selectByName(new_task_name);

                if(find_plug_task_state == null){
                    plugTaskStateService.addTaskState(plugTaskState);//新增记录
                }else{
                    plugTaskState.setId(find_plug_task_state.getId());
                    plugTaskStateService.updateTime(plugTaskState);//修改记录
                }
                plugLoggerRecord.setState(0);
                plugLoggerRecord.setCreateTime(new Date());
                plugLoggerRecord.setMessage("");
                if(plugLoggerRecord.getToNumber() != 0 && plugLoggerRecord.getToNumber()!=plugLoggerRecord.getFromNumber()) {
                    if(plugBackupRecordList.size()!=0) {

                        for (int j = 0; j < plugBackupRecordList.size(); j++) {
                            PlugBackupRecord temp = plugBackupRecordList.get(j);
                            if(temp.getActionType()!=plugLoggerRecord.getActionType()){
                                plugBackupRecordList.add(plugLoggerRecord);
                            }
                        }
                    }else {
                        plugBackupRecordList.add(plugLoggerRecord);
                    }
                }
                if(plugBackupRecordList != null && plugBackupRecordList.size() > 0) {
                    plugBackupRecordService.saveBatch(plugBackupRecordList);
                }
            } catch (Exception e){
                logger.error("即时任务执行异常！"+e);
                plugTaskState.setTaskState("异常");
                plugTaskState.setMessage("从" + indexLong[0] + "运行至第" +indexLong[1]+ ",本次从" +
                        (indexLong[0] + ((i-1) * KeyUtil.compareMaxNumber)) + "运行至" +
                        (indexLong[0] + ((i) * KeyUtil.compareMaxNumber)) + "，异常信息：" + e.getMessage());
                plugTaskState.setEndTime(new Date());
                if(plugTaskStateService.selectByName(new_task_name)==null || plugTaskState.getId() == null){
                    plugTaskStateService.addTaskState(plugTaskState);//新增记录
                }else{

                    plugTaskStateService.updateTime(plugTaskState);//修改记录
                }
                plugLoggerRecord.setState(1);
                plugLoggerRecord.setCreateTime(new Date());
                if(e.getMessage()==null){
                    plugLoggerRecord.setMessage("数据库连接失败，啥都没拿到");
                }else {
                    plugLoggerRecord.setMessage("" + e.getMessage());
                }
                if(plugLoggerRecord.getToNumber() != 0) {
                    plugBackupRecordList.add(plugLoggerRecord);
                    if(plugBackupRecordList.size()!=0) {
                        for (int j = 0; j < plugBackupRecordList.size(); j++) {
                            PlugBackupRecord temp = plugBackupRecordList.get(j);
                            if(temp.getActionType()!=plugLoggerRecord.getActionType()){
                                plugBackupRecordList.add(plugLoggerRecord);
                            }
                        }
                    }else {
                        plugBackupRecordList.add(plugLoggerRecord);
                    }
                }
                if(plugBackupRecordList != null && plugBackupRecordList.size() > 0) {
                    plugBackupRecordService.saveBatch(plugBackupRecordList);
                }
                break;
            }
            logger.info("-------------------page:{}----total:{}-------------------", page,total);


        }

    }
}
